package com.topfinance.xml;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class MsgHeader {
	/*
	 * BeginFlag 起始标识 VersionID 版本号 OrigSender 报文发起人 OrigSenderSID 发送系统号
	 * OrigReceiver 报文接收人 OrigReceiverSID 接收系统号 OrigSendDate 报文发起日期 OrigSendTime
	 * 报文发起时间 StructType 格式类型 MesgType 报文类型代码 MesgID 通信级标识号 MesgRefID 通信级参考号
	 * MesgPriority 报文优先级 MesgDirection 报文传输方向 Reserve （保留域） EndFlag 结束标识
	 */

	private static MsgHeader instance = null;
	public static final String Begin_Flag = "{H:"; // 标识报头块开始，固定使用：{H:
	public static final String Version_ID = "01"; // 固定填写01；
	public static final String MesgPriority = "3"; // 消息优先级
	public static final String MesgDirection = "U"; // 报文传输方向,由行内发出：U 由NPC发出：D
	public static final String Reserve = "000000000"; // 保留域：8位
	public static final String End_Flag = "}\r\n"; // 标识报头块结束，固定使用：标识报头块结束，固定使用：}\r\n

	// 起始标识
	private String beginFlag = Begin_Flag;

	// 版本号
	private String versionID = Version_ID;

	// OrigSender 报文发起人
	private String origSender;

	// OrigSenderSID 发送系统号
	private String origSenderSID;

	// OrigReceiver 报文接收人
	private String origReceiver;

	// OrigReceiverSID 接收系统号
	private String origReceiverSID;

	// OrigSendDate 报文发起日期
	private String origSendDate;

	// OrigSendTime 报文发起时间
	private String origSendTime;

	// StructType 格式类型
	private String structType;

	// MesgType 报文类型代码
	private String mesgType;

	// MesgID 通信级标识号
	private String mesgID;

	// MesgRefID 通信级参考号
	private String mesgRefID;

	// MesgPriority 报文优先级
	private String mesgPriority = MesgPriority;

	// MesgDirection 报文传输方向
	private String mesgDirection = MesgDirection; // 报文加密标识

	// Reserve （保留域）
	private String reserve = Reserve; // （保留域）

	// EndFlag 结束标识
	private String endFlag = End_Flag;

	private byte[] beginFlagA;//起始标识
	private byte[] versionIDA; //版本号
	private byte[] origSenderA; //报文发起人
	private byte[] origSenderSIDA; //发送系统号
	private byte[] origReceiverA; //报文接收人
	private byte[] origReceiverSIDA; //接收系统号
	private byte[] origSendDateA; //报文发起日期
	private byte[] origSendTimeA; //报文发起时间
	private byte[] structTypeA; //格式类型
	private byte[] mesgTypeA; //报文类型代码
	private byte[] mesgIDA; //通信级标识号
	private byte[] mesgRefIDA; //通信级参考号
	private byte[] mesgPriorityA; //报文优先级
	private byte[] mesgDirectionA; //报文传输方向
	private byte[] reserveA; //（保留域）
	private byte[] endFlagA; //结束标识

	private MsgHeader(String ins) {
		setBeginFlag();
		setVersionID();
		//setMesgPriority();
		setEndFlag();
	}

	public static MsgHeader getInstance() {
		if (instance == null) {
			instance = new MsgHeader(null);
		}
		return instance;
	}

	public MsgHeader() {
		super();
		setBeginFlag();
		setVersionID();
		//setMesgPriority();
		setEndFlag();
	}	
	
	public MsgHeader(String origSender, String origSenderSID, String origReceiver, String origReceiverSID, String origSendDate, String origSendTime, String structType, String mesgType, String mesgID, String mesgRefID, String mesgPriority, String mesgDirection, String reserve) {
		super();
		this.origSender = origSender;
		this.origSenderSID = origSenderSID;
		this.origReceiver = origReceiver;
		this.origReceiverSID = origReceiverSID;
		this.origSendDate = origSendDate;
		this.origSendTime = origSendTime;
		this.structType = structType;
		this.mesgType = mesgType;
		this.mesgID = mesgID;
		this.mesgRefID = mesgRefID;
		this.mesgPriority = mesgPriority;
		this.mesgDirection = mesgDirection;
		this.reserve = reserve;
		setBeginFlag();
		setVersionID();
		setMesgPriority();
		setEndFlag();

	}

	//BeginFlag
	public String getBeginFlag() {
		return beginFlag;
	}
	private void setBeginFlag() {
		this.beginFlagA = MsgHeader.Begin_Flag.getBytes();
	}
	
	//VersionID
	public String getVersionID() {
		return versionID;
	}
	private void setVersionID() {
		this.versionIDA = MsgHeader.Version_ID.getBytes();
	}
	
	//OrigSender
	public String getOrigSender() {
		return new String(this.origSenderA);
	}
	public void setOrigSender(String OrigSender) {
		this.origSenderA = OrigSender.getBytes();
	}
	
	//OrigSenderSID
	public String getOrigSenderSID() {
		return new String(this.origSenderSIDA);
	}
	public void setOrigSenderSID(String OrigSenderSID) {
		this.origSenderSIDA = OrigSenderSID.getBytes();
	}
	
	//OrigReceiver
	public String getOrigReceiver() {
		return new String(this.origReceiverA);
	}
	public void setOrigReceiver(String OrigReceiver) {
		this.origReceiverA = OrigReceiver.getBytes();
	}
	
	//OrigReceiverSID
	public String getOrigReceiverSID() {
		return new String(this.origReceiverSIDA);
	}
	public void setOrigReceiverSID(String OrigReceiverSID) {
		this.origReceiverSIDA = OrigReceiverSID.getBytes();
	}
		
	//OrigSendDate
	public String getOrigSendDate() {
		return new String(this.origSendDateA);
	}
	public void setOrigSendDate(String origSendDate) {
		this.origSendDateA = origSendDate.getBytes();
	}
	
	//OrigSendTime
	public String getOrigSendTime() {
		return new String(this.origSendTimeA);
	}
	public void setOrigSendTime(String origSendTime) {
		this.origSendTimeA = origSendTime.getBytes();
	}

	//StructType
	public String getStructType() {
		return new String(this.structTypeA);
	}
	public void setStructType(String structType) {
		this.structTypeA = structType.getBytes();
	}

	//MesgType
	public String getMesgType() {
		return new String(this.mesgTypeA);
	}
	public void setMesgType(String mesgType) {
		this.mesgTypeA = mesgType.getBytes();
	}
	
	//MesgID
	public String getMesgID() {
		return new String(this.mesgIDA);
	}
	public void setMesgID(String mesgID) {
		this.mesgIDA = mesgID.getBytes();
	}
	
	//MesgRefID
	public String getMesgRefID() {
		return new String(this.mesgRefIDA);
	}
	public void setMesgRefID(String mesgRefID) {
		this.mesgRefIDA = mesgRefID.getBytes();
	}
	
	//MesgPriority
	public String getMesgPriority() {
		return mesgPriority;
	}
	private void setMesgPriority() {
		this.mesgPriorityA = MsgHeader.MesgPriority.getBytes();
	}
	
	//MesgDirection
	public String getMesgDirection() {
		return mesgDirection;
	}
	private void setMesgDirection() {
		this.mesgDirectionA = MsgHeader.MesgDirection.getBytes();
	}

	//Reserve
	public String getReserve() {
		return reserve;
	}
	public void setReserve() {
		this.reserveA = MsgHeader.Reserve.getBytes();
	}
	
	//EndFlag
	public String getEndFlag() {
		return endFlag;
	}
	public void setEndFlag() {
		this.endFlagA = MsgHeader.End_Flag.getBytes();
	}

	public void parse(String head) throws Exception {
		parse(head.getBytes());
	}

	public void parse(byte[] head) throws Exception {
		// 1.BeginFlag	起始标识	0	3	x	M
		this.beginFlagA = preTagHeader(head, 0, 3, 'x');

		// 2.VersionID	版本号	3	2	n	M
		this.versionIDA = preTagHeader(head, 3, 2, 'n');

		// 3.OrigSender	报文发起人	5	12	x	M
		this.origSenderA = preTagHeader(head, 5, 12, 'x');

		// 4.OrigSenderSID	发送系统号	17	4	x	M
		this.origSenderSIDA = preTagHeader(head, 17, 4, 'x');

		// 5.OrigReceiver	报文接收人	21	12	x	M
		this.origReceiverA = preTagHeader(head, 21, 12, 'x');

		// 6.OrigReceiverSID	接收系统号	33	4	x	M
		this.origReceiverSIDA = preTagHeader(head, 33, 4, 'x');

		// 7.OrigSendDate	报文发起日期	37	8	d	M
		this.origSendDateA = preTagHeader(head, 37,8, 'x');

		// 8.OrigSendTime	报文发起时间	45	6	t	M
		this.origSendTimeA = preTagHeader(head, 45, 6, 'x');

		// 9.StructType	格式类型	51	3	x	M
		this.structTypeA = preTagHeader(head, 51, 3, 'x');

		// 10.MesgType	报文类型代码	54	20	x	M
		this.mesgTypeA = preTagHeader(head, 54, 20, 'x');

		// 11.MesgID	通信级标识号	74	20	x	M
		this.mesgIDA = preTagHeader(head, 74, 20, 'x');

		// 12.MesgRefID	通信级参考号	94	20	x	O
		this.mesgRefIDA = preTagHeader(head, 94, 20, 'x');

		// 13.MesgPriority	报文优先级	114	1	n	M
		this.mesgPriorityA = preTagHeader(head, 114, 1, 'x');

		// 14.MesgDirection	报文传输方向	115	1	X	M
		this.mesgDirectionA = preTagHeader(head, 115, 1, 'x');

		// 15.Reserve	（保留域）	116	9	x	O
		this.reserveA = preTagHeader(head, 116, 9, 'x');

		// 16.EndFlag	结束标识	125	3	x	M
		this.endFlagA = preTagHeader(head, 125, 3, 'x');
	}

	public String getHeaderAsString() {
		return new String(getHeaderAsArray());
	}

	public byte[] getHeaderAsArray() {
		byte[] res = new byte[128];
		int pos = 0;
		// 1.BeginFlag	起始标识	0	3	x	M
		System.arraycopy(postTagHeader(this.beginFlagA, 3, 'x'), 0, res, pos, 3);
		pos += 3;

		// 2.VersionID	版本号	3	2	n	M
		System.arraycopy(postTagHeader(this.versionIDA, 2, 'n'), 0, res, pos, 2);
		pos += 2;

		// 3.OrigSender	报文发起人	5	12	x	M
		System.arraycopy(postTagHeader(this.origSenderA, 12, 'x'), 0, res, pos, 12);
		pos += 12;

		// 4.OrigSenderSID	发送系统号	17	4	x	M
		System.arraycopy(postTagHeader(this.origSenderSIDA, 4, 'x'), 0, res, pos, 4);
		pos += 4;

		// 5.OrigReceiver	报文接收人	21	12	x	M
		System.arraycopy(postTagHeader(this.origReceiverA, 12, 'x'), 0, res, pos, 12);
		pos += 12;

		// 6.OrigReceiverSID	接收系统号	33	4	x	M
		System.arraycopy(postTagHeader(this.origReceiverSIDA, 4, 'x'), 0, res, pos, 4);
		pos += 4;

		// 7.OrigSendDate	报文发起日期	37	8	d	M
		System.arraycopy(postTagHeader(this.origSendDateA, 8, 'x'), 0, res, pos, 8);
		pos += 8;

		// 8.OrigSendTime	报文发起时间	45	6	t	M
		System.arraycopy(postTagHeader(this.origSendTimeA, 6, 'x'), 0, res, pos, 6);
		pos += 6;

		// 9.StructType	格式类型	51	3	x	M
		System.arraycopy(postTagHeader(this.structTypeA, 3, 'x'), 0, res, pos, 3);
		pos += 3;

		// 10.MesgType	报文类型代码	54	20	x	M
		System.arraycopy(postTagHeader(this.mesgTypeA, 20, 'x'), 0, res, pos, 20);
		pos += 20;

		// 11.MesgID	通信级标识号	74	20	x	M
		System.arraycopy(postTagHeader(this.mesgIDA, 20, 'x'), 0, res, pos, 20);
		pos += 20;

		// 12.MesgRefID	通信级参考号	94	20	x	O
		System.arraycopy(postTagHeader(this.mesgRefIDA, 20, 'x'), 0, res, pos, 20);
		pos += 20;

		// 13.MesgPriority	报文优先级	114	1	n	M
		System.arraycopy(postTagHeader(this.mesgPriorityA, 1, 'x'), 0, res, pos, 1);
		pos += 1;

		// 14.MesgDirection	报文传输方向	115	1	X	M
		System.arraycopy(postTagHeader(this.mesgDirectionA, 1, 'x'), 0, res, pos, 1);
		pos += 1;

		// 15.Reserve	（保留域）	116	9	x	O
		System.arraycopy(postTagHeader(this.reserveA, 9, 'x'), 0, res, pos, 9);
		pos += 9;

		// 16.EndFlag	结束标识	125	3	x	M
		System.arraycopy(postTagHeader(this.endFlagA, 3, 'x'), 0, res, pos, 3);
		pos += 3;

		return res;
	}

	/**
	 * @describe 根据n型左补0，x型右补空
	 * @return 只包含内容的数组
	 * @throws
	 * 
	 */
	public static byte[] preTagHeader(byte data[], int begin, int len, char type) {
		// 仅仅对x和n进行处理
		int start = begin;
		int end = begin + len;
		if (type != 'd' || type != 't') {
			for (int i = begin; i < begin + len; i++) {
				byte c = data[i];
				if (type == 'x') {
					// == ' '?
					if (c == 64) {
						end = i - 1;
						break;
					} else
						continue;
				} else if (type == 'n') {
					// == 32?
					if (c != 32) {
						start = i;
						break;
					}
				}
			}
		}
		byte[] res = new byte[end - start];
		System.arraycopy(data, begin, res, 0, end - begin);
		return res;
	}

	/**
	 * @describe 根据n型左补0，x型右补空
	 * @return 只包含内容的数组
	 * @throws
	 * 
	 */
	public static byte[] postTagHeader(byte data[], int len, char type) {
		// 仅仅对x和n进行处理
		byte[] res = new byte[len];
		if (type != 'd' || type != 't') {
			if (type == 'x') {
				System.arraycopy(data, 0, res, 0, data.length);
				for (int i = 0; i < len - data.length; i++)
					res[data.length + i] = 32;
			} else if (type == 'n') {
				System.arraycopy(data, 0, res, len - data.length, data.length);
				for (int i = 0; i < len - data.length; i++)
					res[i] = 48;
			}
			return res;
		} else
			return data;
	}

	public static void main(String[] args) {
		try {
//			FileInputStream fis = new FileInputStream(
//					"E:\\DevSpace\\ECADOS\\ecdsRepo\\ecadosEJB\\ecdsMsg\\ecds.001.001.01.xml");
//			byte[] bb = new byte[fis.available()];
//			fis.read(bb);
//			byte hd[] = new byte[200];
//			System.arraycopy(bb, 0, hd, 0, 200);
//			MsgHeader head = MsgHeader.getInstance();
//			head.parse(hd);
//			String preStr = new String(hd);
//			byte res[] = head.getHeaderAsArray();
//			String convertedStr = new String(res);
//			System.out.print("[SRC0]" + preStr);
//			System.out.print("[DEST]" + convertedStr);
//			System.out.println("[Result0]" + preStr.equals(convertedStr));

			MsgHeader head2 = MsgHeader.getInstance();
			head2.setOrigSender("308581005500");
			head2.setOrigSenderSID("IBPS");
			head2.setOrigReceiver("102100033300");
			head2.setOrigReceiverSID("IBPS");
			head2.setOrigSendDate("20100220");
			head2.setOrigSendTime("111111");
			head2.setStructType("XML");
			head2.setMesgType("ibps.101.001.01");
			head2.setMesgID("A1234B1234C1234D1234");
			head2.setMesgRefID("00000000000000000000");
			head2.setMesgPriority();
			head2.setMesgDirection();
			head2.setReserve();
			String pre1Str = head2.getHeaderAsString();
			System.out.print("[SRC2]" + pre1Str);
			
			MsgHeader head = MsgHeader.getInstance();
			head.parse(head2.getHeaderAsArray());
			System.out.println("[OrigSender]" + head.getOrigSender());
			System.out.println("[OrigSenderSID]" + head.getOrigSenderSID());
			System.out.println("[OrigReceiver]" + head.getOrigReceiver());
			System.out.println("[OrigReceiverSID]" + head.getOrigReceiverSID());
			System.out.println("[OrigSendDate]" + head.getOrigSendDate());
			System.out.println("[OrigSendTime]" + head.getOrigSendTime());
			System.out.println("[StructType]" + head.getStructType());
			System.out.println("[MesgType]" + head.getMesgType());
			System.out.println("[MesgID]" + head.getMesgID());
			System.out.println("[MesgRefID]" + head.getMesgRefID());
			System.out.println("[MesgType]" + head.getMesgType());
			System.out.println("[MesgPriority]" + head.getMesgPriority());
			System.out.println("[MesgDirection]" + head.getMesgDirection());
			System.out.println("[Reserve]" + head.getReserve());
//		} catch (FileNotFoundException e1) {
//			e1.printStackTrace();
//		} catch (IOException e1) {
//			e1.printStackTrace();
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}
}
